#include <cstdio>
#include <fcntl.h>
#include <unistd.h>
#include <iservice_registry.h>
#include "usart_proxy.h"
#include <iostream>

using namespace OHOS;
using namespace OHOS::Usart_Standard;
const char helpdoc[]=
"help ------------------- show this doc"
"open,close,is_open ----- get status\n"
"read,readline ---------- read data\n"
"write ------------------ write data\n"
"exit ------------------- close the serial (if open) and exit\n"
;
namespace OP
{
enum Opcode{
    OPEN,CLOSE,IS_OPEN,READ,WRITE,READLINE,HELP,EXIT,NO_OP=-1,
} ; 
} // namespace OP
OP::Opcode get_opcode(const std::string& op){
    using namespace OP;
    const static std::map<std::string,OP::Opcode> mp{
        {"open",OPEN },{"close",CLOSE},{"is_open",IS_OPEN},{"read",READ},{"write",WRITE},{"readline",READLINE},
        {"help",HELP},{"exit",EXIT}
    };
    auto it=mp.find(op);
    if(it==mp.end()){
        return NO_OP;
    }
    return it->second;
}


int main() {
    using namespace std;
    auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
    if(samgr ==nullptr){
        fprintf(stderr, "Get samgr failed\n");
        return 0;
    }
    sptr<IRemoteObject> object = samgr->GetSystemAbility(9901);
    if (object == nullptr)
    {
        fprintf(stderr, "Get UsartService failed\n");
        return 0;
    }
    auto proxy = iface_cast<IUsartAbility>(object);
    if (proxy == nullptr)
    {
        fprintf(stderr, "Cast proxy failed\n");
        return 0;
    }
    //真正的端口是 “dev/ttyS7”
    const std::string name = "/dev/ttyS7";
    std::string op;
    cout << '>';
    while(cin>>op){
        switch(get_opcode(op)){
            case OP::OPEN:{
                proxy->open(name);
            }break;
            case OP::CLOSE:{
                proxy->close(name);
            }break;
            case OP::IS_OPEN:{
                bool res=proxy->is_open(name);
                cout<<"port "<<name<<(res?"is open":"is not open")<<'\n';
            }break;
            case OP::READ:{
                cout<<"how many bytes? : ";
                size_t bytes;
                cin>>bytes;
                auto res =proxy->read(name,bytes);
                cout<<"read get : "<<res<<'\n';
            }break;
            case OP::WRITE:{
                std::string data;
                cout <<"type what you want to write: ";
                cin>> data;
                proxy->write(name,data);
            }break;
            case OP::READLINE:{
                auto res =proxy->readline(name);
                cout<<"readline get : "<<res<<'\n';
            }break;
            case OP::HELP:{
                cout<<helpdoc;
            }break;
            case OP::EXIT:{
                if(proxy->is_open(name)){
                    proxy->close(name);
                };
                return 0;
            }
            default:break;
        }
        cout << '>';
    }
    int ret1 = proxy->open(name);
    if (ret1 != 0) {
        fprintf(stderr, "open uart failed\n");
        return 0;
    }

    bool ret2 =  proxy->is_open(name);
    if (!ret2) {
        fprintf(stderr, "is_open uart failed\n");
        return 0;
    }

    std::string s = "test!";
    proxy->write(name, s);

    fprintf(stderr, "start readlint!\n");
    std::string ret4 = proxy->readline(name);

    fprintf(stderr, "readline: %s", ret4.c_str());
    return 0;
}